基础图元 Box

创建一个长方体(Box)

效果图:

步骤:

  1. 申请一个精度

    1
    2
    3
    osg::ref_ptr<osg::TessellationHints> hints = new osg::TessellationHints;

    hints->setDetailRatio(0.5);
  2. 申请一个Shape(需要赋值精细度)

    1
    2
    3
    4
    osg::ref_ptr<osg::ShapeDrawable> shape = new osg::ShapeDrawable(new osg::Box(osg::Vec3(0.0, 0.0, 0.0), 1.0, 10.0, 10.0), hints.get());

    //赋值为灰色,半透明
    shape->setColor(osg::Vec4(0.5, 0.5, 0.5, 0.5));
  3. 申请一个材质

    1
    2
    3
    4
    5
    6
    osg::ref_ptr<osg::Material> material = new osg::Material;

    material->setAmbient(osg::Material::FRONT_AND_BACK, osg::Vec4f(1.0, 1.0, 1.0, 0.5));
    material->setDiffuse(osg::Material::FRONT_AND_BACK, osg::Vec4f(1.0, 1.0, 1.0, 0.5));
    material->setSpecular(osg::Material::FRONT_AND_BACK, osg::Vec4f(1.0, 1.0, 1.0, 0.5));
    material->setShininess(osg::Material::FRONT_AND_BACK, 6.0);
  4. 申请一个纹理和Image

    1
    2
    3
    4
    5
    6
    7
    8
    osg::ref_ptr<osg::Texture2D> texture2D = new osg::Texture2D;
    osg::ref_ptr<osg::Image> image = new osg::Image;

    image = osgDB::readImageFile("Images/whitemetal_diffuse.jpg");

    if (image.valid()) {
    texture2D->setImage(image.get());
    }
  5. 申请一个Geode作为函数返回值

    1
    2
    3
    4
    5
    6
    osg::ref_ptr<osg::Geode> geode = new osg::Geode;

    geode->getOrCreateStateSet()->setAssociatedModes(material.get(), osg::StateAttribute::ON);
    geode->getOrCreateStateSet()->setMode(GL_BLEND, osg::StateAttribute::ON);
    geode->getOrCreateStateSet()->setMode(GL_DEPTH_TEST, osg::StateAttribute::ON);
    geode->getOrCreateStateSet()->setTextureAttributeAndModes(0, texture2D.get(), osg::StateAttribute::ON);
  6. geode中绘制shape

    1
    geode->addDrawable(shape.get());
  7. 将返回的Geode添加到group

    1
    group->addChild(CreateBox());
  8. 完整代码

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    #include <osgViewer/Viewer>
    #include <osgDB/ReadFile>
    #include <osgGA/GUIEventAdapter>
    #include <osgViewer/ViewerEventHandlers>
    #include <osg/Geode>
    #include <osg/ShapeDrawable>
    #include <osg/Material>
    #include <osg/StateSet>
    #include <osg/Image>
    #include <osg/Texture2D>
    #include <iostream>
    using namespace std;

    osg::ref_ptr<osg::Geode> CreateBox() {

    osg::ref_ptr<osg::Geode> geode = new osg::Geode;
    osg::ref_ptr<osg::TessellationHints> hints = new osg::TessellationHints;
    osg::ref_ptr<osg::ShapeDrawable> shape = new osg::ShapeDrawable(new osg::Box(osg::Vec3(0.0, 0.0, 0.0), 1.0, 10.0, 10.0), hints.get());
    osg::ref_ptr<osg::Material> material = new osg::Material;
    osg::ref_ptr<osg::Texture2D> texture2D = new osg::Texture2D;
    osg::ref_ptr<osg::Image> image = new osg::Image;

    hints->setDetailRatio(0.5);

    shape->setColor(osg::Vec4(0.5, 0.5, 0.5, 0.5));

    material->setAmbient(osg::Material::FRONT_AND_BACK, osg::Vec4f(1.0, 1.0, 1.0, 0.5));
    material->setDiffuse(osg::Material::FRONT_AND_BACK, osg::Vec4f(1.0, 1.0, 1.0, 0.5));
    material->setSpecular(osg::Material::FRONT_AND_BACK, osg::Vec4f(1.0, 1.0, 1.0, 0.5));
    material->setShininess(osg::Material::FRONT_AND_BACK, 6.0);

    image = osgDB::readImageFile("Images/whitemetal_diffuse.jpg");
    if (image.valid()) {
    texture2D->setImage(image.get());
    }

    //set state
    geode->getOrCreateStateSet()->setAssociatedModes(material.get(), osg::StateAttribute::ON);
    geode->getOrCreateStateSet()->setMode(GL_BLEND, osg::StateAttribute::ON);
    geode->getOrCreateStateSet()->setMode(GL_DEPTH_TEST, osg::StateAttribute::ON);
    geode->getOrCreateStateSet()->setTextureAttributeAndModes(0, texture2D.get(), osg::StateAttribute::ON);
    geode->addDrawable(shape.get());

    return geode;
    }

    int main() {

    osg::ref_ptr<osgViewer::Viewer> viewer = new osgViewer::Viewer;
    osg::ref_ptr<osg::Group> group = new osg::Group;

    group->addChild(CreateBox());
    viewer->setSceneData(group.get());

    return viewer->run();
    }